import React, {PureComponent} from "react";
import {Form, Icon, Input, InputNumber, notification, Select, Table, Modal, Tooltip} from "antd";
import {connect} from "react-redux";
import {paginationProps, tableProps} from "../../lib/ui";
import {
    changeSettlement,
    del,
    feeList,
    getBusinessCodeList,
    getCurrencyList,
    getFeeList,
    getFollows,
    getMyColumns,
    getRateList,
    lockFeeById,
    modifyPart,
    query,
    select,
    showEdit,
    unlockFeeById,
    updateDataSource,
    updateFee
} from "./actions";
import {getCurrentOrganization, getLastFilter, getPrincipal} from "../../lib/identity";
import {getLockStatus, getStatusText} from "../../lib/func";
import AddressInfo from "../../components/AddressInfo";
import NoInfo from "../../components/NoInfo";
import {getAllOrganization} from "../organization/actions";
import {getCarrierList, getClientList, organizations} from "../home/actions";
import {getCoach} from "../zadOrder/actions";

const LAST_FILTER = "zadOrderPayable";

const {confirm} = Modal;

const {Option} = Select;

const EditableContext = React.createContext();

const EditableRow = ({form, index, ...props}) => (
    <EditableContext.Provider value={form}>
        <tr {...props} />
    </EditableContext.Provider>
);

const EditableFormRow = Form.create()(EditableRow);

class EditableCell extends React.Component {
    state = {
        editing: false,
    };

    toggleEdit = () => {
        const editing = !this.state.editing;
        this.setState({editing}, () => {
            if (editing) {
                this.input.focus();
            }
        });
    };

    save = e => {
        const {record, handleSave} = this.props;
        this.form.validateFields((error, values) => {
            if (error && error[e.currentTarget.id]) {
                return;
            }
            this.toggleEdit();
            handleSave({...record, ...values});
        });
    };

    onChange = (e, onChange) => {
        this.form.validateFields((error, values) => {
            if (error && error[e.currentTarget.id]) {
                return;
            }
            this.toggleEdit();
            onChange(e);
        });
    };

    renderCell = form => {
        this.form = form;
        const {children, dataIndex, record, onChange, options = [], placeholder, inputType} = this.props;
        const {editing} = this.state;
        let column;
        if (inputType === "number") {
            column = <InputNumber ref={node => (this.input = node)} onPressEnter={this.save} onBlur={this.save}/>;
        } else if (inputType === "select") {
            column = <Select placeholder={placeholder} ref={node => (this.input = node)} style={{width: 100}}
                             onChange={e => this.onChange(e, onChange)} allowClear={true}>
                {options.map((item, index) => (
                    <Option key={index} value={item.value}>
                        {item.label}
                    </Option>
                ))}
            </Select>;
        } else {
            column = <Input ref={node => (this.input = node)} onPressEnter={this.save} onBlur={this.save}/>;
        }
        return editing ? (
            <Form.Item style={{margin: 0}}>
                {form.getFieldDecorator(dataIndex, {
                    initialValue: record[dataIndex],
                })(column)}
            </Form.Item>
        ) : (
            <div
                className="editable-cell-value-wrap"
                style={{paddingRight: 24}}
                onClick={this.toggleEdit}
            >
                {children}
            </div>
        );
    };

    render() {
        const {
            editable,
            dataIndex,
            title,
            record,
            index,
            inputType,
            options,
            placeholder,
            onChange,
            handleSave,
            children,
            valueField,
            labelField,
            ...restProps
        } = this.props;
        return (
            <td {...restProps}>
                {editable ? (
                    <EditableContext.Consumer>{this.renderCell}</EditableContext.Consumer>
                ) : (
                    children
                )}
            </td>
        );
    }
}

class List extends PureComponent {

    state = {rowId: ""};
    // 选中行
    onClickRow = (record) => {
        return {
            onClick: () => {
                this.setState({
                    rowId: record.id,
                });
            },
        };
    }

    setRowClassName = (record) => {
        // 自己创建的可以在列表编辑
        const owner = record.userId === getPrincipal().id;
        let className = owner ? 'editable-row' : '';
        // 已结算   #d0d0d0
        // 订单锁定   #BEBEBE
        if (record.outSettlement === "已结算") {
            className = className + " table-color-lock";
        } else if (record.alert) {
            // 即将发运未完成跟进   #FFAF60
            className = className + " table-color-send-no-finish";
        }
        return record.id === this.state.rowId ? 'clickRowStyl ' + className : className;
    }

    onPageChange = (page, pageSize) => {
        const {dispatch, filter} = this.props;
        dispatch(query({
            "userId": getPrincipal().id, ...filter,
            "organizationId": getCurrentOrganization(),
            page,
            pageSize
        }));
    };

    handleShowEdit = row => {
        const {dispatch} = this.props;
        dispatch(showEdit(row));
        dispatch(getFollows(row.id));
        dispatch(getBusinessCodeList());
        dispatch(feeList(row.id));
    };

    handleDelete = id => {
        const {dispatch, page, pageSize, filter} = this.props;
        dispatch(del(id)).then(() => {
            dispatch(query({
                "userId": getPrincipal().id, ...filter,
                "organizationId": getCurrentOrganization(),
                page,
                pageSize
            }));
        });
    };


    saveInvoice = e => {
        const {dispatch, dataSource} = this.props;
        const rowId = this.state.rowId;
        // 弹窗确认
        confirm({
            title: '是否确定把发票状态改为',
            content: e,
            onOk() {
                const data = dataSource.find(item => item.id === rowId);
                if (data) {
                    data.outInvoice = e;
                    data.opId = getPrincipal().id;
                    data.type = "IN_OR_SETTLEMENT";
                    dispatch(modifyPart({...data, opId: getPrincipal().id})).then(action => {
                        if (action.error !== true) {
                            let deleteIndex = dataSource.findIndex(item => item.id === rowId);
                            delete data.type;
                            dataSource.splice(deleteIndex, 1, data);
                            dispatch(updateDataSource(dataSource));
                        } else {
                            notification.error({
                                message: '保存失败:' + action.message
                            });
                        }
                    });
                }
            },
            onCancel() {
            },
        });
    };
    saveSettlement = e => {
        const {dispatch, dataSource, filter = {}, page, pageSize} = this.props;
        const rowId = this.state.rowId;
        const data = dataSource.find(item => item.id === rowId);
        // 判断是否还箱 COC 线路才需要判断
        if ((data.originPlace != null && data.originPlace.toUpperCase().indexOf("COC") >= 0) ||
            (data.destPlace != null && data.destPlace.toUpperCase().indexOf("COC") >= 0)) {
            if (data.packageReturnDate === null || data.packageReturnDate.length === 0) {
                notification.error({
                    message: '未填写实际还箱日期，锁账失败'
                });
                return;
            }
        }
        // 弹窗确认
        confirm({
            title: '是否确定把结算状态改为',
            content: e,
            onOk() {
                if (data) {
                    data.outSettlement = e;
                    data.opId = getPrincipal().id;
                    data.type = "IN_OR_SETTLEMENT";
                    dispatch(changeSettlement([data.id])).then(action => {
                        if (action.error !== true) {
                            dispatch(query({
                                ...filter,
                                "userId": getPrincipal().id,
                                "organizationId": getCurrentOrganization(),
                                page,
                                pageSize
                            }));
                        }
                    });
                }
            },
            onCancel() {
            },
        });
    };

    handleSave = row => {
        if (row.status === "CONFIRMED") {
            notification.error({
                message: '已锁定,不能修改'
            });
            return;
        }
        const {dispatch, dataSource} = this.props;
        row.opId = getPrincipal().id;
        dispatch(modifyPart(row)).then(action => {
            if (action.error !== true) {
                let deleteIndex = dataSource.findIndex(item => item.id === row.id);
                dataSource.splice(deleteIndex, 1, row);
                dispatch(updateDataSource(dataSource));
            } else {
                notification.error({
                    message: '保存失败:' + action.message
                });
            }
        });

    };

    componentWillMount() {
        const {dispatch, page, pageSize} = this.props;
        dispatch(organizations(getPrincipal().id));
        dispatch(getMyColumns("zadOrderPayable")).then(action => {
            if (action.error !== true) {
                let fields = getLastFilter(LAST_FILTER);
                if (fields === null || fields === undefined) {
                    fields = {};
                }
                dispatch(query({
                    ...fields,
                    "userId": getPrincipal().id,
                    "organizationId": getCurrentOrganization(),
                    page,
                    pageSize
                }));
                dispatch(getFeeList());
                dispatch(getAllOrganization());
                dispatch(getRateList());
                dispatch(getCurrencyList());
                dispatch(getCoach());
                dispatch(getClientList(getCurrentOrganization()));
                dispatch(getCarrierList(getCurrentOrganization()));
            } else {
                notification.error({
                    message: '获取自定义列失败'
                });
            }

        });

    };

    handleSelectChange = (selectedRowKeys) => {
        const {dispatch} = this.props;
        dispatch(select(selectedRowKeys));
    };

    lockFeeById = id => {
        const {dispatch, page, pageSize, filter} = this.props;
        dispatch(lockFeeById(id)).then(action => {
            if (action.error !== true) {
                dispatch(query({
                    "userId": getPrincipal().id, ...filter,
                    "organizationId": getCurrentOrganization(),
                    page,
                    pageSize
                }));
                notification.success({
                    message: '锁定成功'
                });
            } else {
                notification.error({
                    message: '锁定失败:' + action.message
                });
            }
        });
    };

    unlockFeeById = id => {
        const {dispatch, page, pageSize, filter} = this.props;
        dispatch(unlockFeeById(id)).then(action => {
            if (action.error !== true) {
                dispatch(query({
                    "userId": getPrincipal().id, ...filter,
                    "organizationId": getCurrentOrganization(),
                    page,
                    pageSize
                }));
                notification.success({
                    message: '解锁成功'
                });
            } else {
                notification.error({
                    message: '解锁失败:' + action.message
                });
            }
        });
    };

    onSaveFee = (rowId, feeName, feeCount, currency) => {
        const {dispatch, dataSource} = this.props;
        // 更新数据库
        const model = {rowId, feeName, feeCount, currency, "type": "OUT"};
        dispatch(updateFee(model)).then(action => {
            if (action.error !== true) {
                let deleteIndex = dataSource.findIndex(item => item.id === rowId);
                const found = dataSource.find(item => item.id === rowId);
                const fees = found.outFeeList || [];
                const record = fees.find(fee => fee.feeName === feeName);
                if (record) {
                    record.feeCount = feeCount;
                    record.currency = currency;
                } else {
                    fees.push({feeName: feeName, feeCount: feeCount, currency: currency});
                }
                dataSource.splice(deleteIndex, 1, found);
                dispatch(updateDataSource(dataSource));
            } else {
                notification.error({
                    message: '保存失败:' + action.message
                });
            }
        });

    };

    // 自定义列辅助功能结束
    render() {
        const {
            page,
            pageSize,
            totalElements,
            selectedRowKeys,
            dataSource,
            loading,
            feeList,
            zadOrderPayableColumns,
            columns, settlementStatusList, invoiceStatusList
        } = this.props;
        const rowSelection = {
            selectedRowKeys,
            columnWidth: '60px',
            onChange: this.handleSelectChange
        };

        const components = {
            body: {
                row: EditableFormRow,
                cell: EditableCell,
            },
        };

        const newColumns = [];
        let isEmpty = false;
        if (columns.length === 0) {
            isEmpty = true;
        }
        zadOrderPayableColumns.forEach(column => {
            if (columns.indexOf(column.label) >= 0 || isEmpty) {
                if ("dateTime" === column.type) {
                    newColumns.push({
                        ...column,
                        title: column.label,
                        dataIndex: column.value,
                        render: text => <span>{text && text.toString().substr(0, 10)}</span>
                    });
                } else if ("number" === column.type) {
                    newColumns.push({
                        ...column,
                        title: column.label,
                        dataIndex: column.value,
                        render: text => <span>{text && Number(text).toFixed(3)}</span>
                    });
                } else if ("money" === column.type) {
                    newColumns.push({
                        ...column,
                        title: column.label,
                        dataIndex: column.value,
                        render: text => <span>{text && Number(text).toFixed(2)}</span>
                    });
                } else if ("status" === column.type) {
                    newColumns.push({
                        title: '状态',
                        dataIndex: 'status',
                        width: column.width,
                        render: text => getLockStatus(text)
                    });
                } else if ("address" === column.type) {
                    newColumns.push({
                        title: column.label,
                        dataIndex: column.value,
                        render: (text) => <AddressInfo {...text}/>,
                        width: column.width
                    });
                } else if ('enum' === column.type) {
                    newColumns.push({
                        title: column.label,
                        dataIndex: column.value,
                        render: (text) => getStatusText(text, column.dataSource),
                        width: column.width
                    });
                } else if ('list' === column.type) {
                    newColumns.push({
                        title: column.label,
                        dataIndex: column.value,
                        render: (text, record) => <NoInfo item={record[column.dataKey]} valueLabel={column.itemKey}/>,
                        width: column.width
                    });
                } else {
                    if (column.clickable === true) {
                        newColumns.push({
                            ...column,
                            title: column.label,
                            dataIndex: column.value,
                            render: (text, record) => (
                                <a
                                    onClick={() => {
                                        this.handleShowEdit(record);
                                    }}
                                >
                                    {text}
                                </a>
                            ),
                            width: column.width
                        });
                    } else if ("账单备注" !== column.label) {
                        let text = column.label;
                        if ("备注" === column.label) {
                            text = "订单备注";
                        }
                        newColumns.push({
                            ...column,
                            title: text,
                            dataIndex: column.value,
                            ellipsis: true,
                            render: text => <Tooltip placement="top" title={text}>{text}</Tooltip>
                        });
                    }
                }
            }
        });
        if (columns.indexOf('账单备注') >= 0) {
            newColumns.push({
                width: 220,
                editable: true,
                title: '账单备注',
                dataIndex: 'billRemark'
            });
        }
        feeList.forEach(item => {
            if (columns.indexOf(item.name) >= 0) {
                newColumns.push({
                    title: item.name,
                    dataIndex: item.name,
                    render: (text, record) => {
                        if (text === undefined || text.length === 0) {
                            return '';
                        }
                        const found = dataSource.find(item => item.id === record.id);
                        const fees = found.outFeeList || [];
                        const foundFee = fees.find(fee => fee.feeName === item.name);
                        if (foundFee && foundFee.status === "LOCK") {
                            return <span>{text}<Icon type="lock"
                                                     onClick={() => this.unlockFeeById(foundFee.id)}/></span>
                        } else {
                            return <span>{text}<Icon type="unlock"
                                                     onClick={() => this.lockFeeById(foundFee.id)}/></span>
                        }
                    },
                    width: 120
                });
            }
        });

        // 加 开票 结算
        newColumns.push({
            title: "是否开票",
            dataIndex: "outInvoice",
            width: 120,
            editable: true,
            options: invoiceStatusList,
            placeholder: "选择开票选项",
            inputType: "select",
            onChange: this.saveInvoice
        });
        newColumns.push({
            title: "是否结算",
            dataIndex: "outSettlement",
            width: 120,
            editable: true,
            options: settlementStatusList,
            placeholder: "选择结算选项",
            inputType: "select",
            onChange: this.saveSettlement
        });

        if (newColumns.length < 5) {
            newColumns.push(
                {
                    title: "",
                    dataIndex: ""
                }
            );
        }

        const editColumns = newColumns.map(col => {
            if (!col.editable) {
                return col;
            }
            return {
                ...col,
                onCell: record => ({
                    record,
                    editable: col.editable,
                    dataIndex: col.dataIndex,
                    title: col.title,
                    options: col.options,
                    placeholder: col.placeholder,
                    inputType: col.inputType,
                    onChange: col.onChange,
                    handleSave: this.handleSave,
                }),
            };
        });

        dataSource.forEach(data => {
            const fees = data.outFeeList || [];
            feeList.forEach(item => {
                if (columns.indexOf(item.name) >= 0) {
                    const found = fees.find(fee => fee.feeName === item.name);
                    if (found && found.feeCount && parseFloat(found.feeCount) !== 0) {
                        let currency = '';
                        if (found.currency === "人民币") {
                            currency = "￥";
                        } else if (found.currency === "美元" || found.currency === "美金") {
                            currency = "$";
                        }
                        if (found.feeCount) {
                            const text = parseFloat(found.feeCount).toFixed(2);
                            data[found.feeName] = currency + text;
                        }
                    } else {
                        data[item.name] = '';
                    }
                    // 隐藏运输费
                    // if (item.name === "运输费" && getPrincipal().admin === false) {
                    //     data[item.name] = "******";
                    // }
                }
            });
        });
        const tablePagination = {
            ...paginationProps,
            total: totalElements,
            current: page,
            pageSize: pageSize,
            onShowSizeChange: (current, newSize) =>
                this.onPageChange && this.onPageChange(1, newSize),
            onChange: this.onPageChange
        };
        return (
            <Table
                {...tableProps}
                columns={editColumns}
                scroll={{x: 1500, y: 'calc(100vh - 480px)'}}
                pagination={tablePagination}
                rowSelection={rowSelection}
                dataSource={dataSource}
                loading={loading}
                components={components}
                onRow={this.onClickRow}
                rowClassName={this.setRowClassName}
            />
        );
    }
}

const
    mapStateToProps = state => {
        return {
            ...state.zadOrderPayable.list,
            zadOrderPayableColumns: state.common.zadOrderPayableColumns,
            columns: state.zadOrderPayable.columns.columns,
            invoiceStatusList: state.common.invoiceStatusList,
            settlementStatusList: state.common.settlementStatusList
        };
    };

export default connect(mapStateToProps)(List);
